import { defineComponent, onMounted, onUnmounted, ref, watch } from "vue";
import { switchStore } from "../../store";
import { getBoundingClientRect, getUUid } from "../../path/until";
import { TypeProps, onkeydown, TypeEmits } from "./until";
import { TypeKeys, TypeWidgetItem } from "@/focus/type";

export default defineComponent({
  name: "focus-widget",
  emits: TypeEmits,
  props: TypeProps,

  setup(props, { emit }) {
    const domRef = ref<HTMLElement>()
    const inject = switchStore.inject()
    const uid = ref(props.widgetId || getUUid())
    // 焦点引擎widgetId可能会被更改，所以需要监听并且更新widgetId
    watch([() => props.goleft, () => props.goright, () => props.scrollNo, () => props.goup, () => props.godown, () => props.sequence], () => {
      updateWidget()
    }, { immediate: true })

    watch(() => inject.state.focusId.value, (focusId, oldFocusId) => {
      if (uid.value === focusId) {
        emit("focus")
      } else if (uid.value === oldFocusId) {
        emit("unfocus")
      }
    }, { immediate: true })
    function updateWidget() {
      inject.createWidget({
        name: "focus-widget",
        uid: uid.value,
        onMoveFocus: props.onMoveFocus as (ev: keyof TypeKeys) => boolean,
        goleft: props.goleft,
        goright: props.goright,
        goup: props.goup,
        godown: props.godown,
        scrollNo: props.scrollNo,
        sequence: props.sequence,
        ele: domRef.value,
        rect: getBoundingClientRect(domRef.value),
      })
    }
    onMounted(() => {
      inject.listenerKeyDown(uid.value, (key, keyEv) => {
        if (inject.state.focusId.value !== uid.value) return
        onkeydown(emit, key, keyEv.keyCode)
      })
      updateWidget()
    })
    onUnmounted(() => {
      inject.unListenerKeyDown(uid.value)
      inject.deleteWidget({ uid: uid.value } as TypeWidgetItem)
    })
    return {
      domRef,
      state: inject.state,
      uid,
    }
  },

  render() {
    return (
      <div id={this.uid} ref="domRef" class={this.state.focusId.value === this.uid ? "fe-focus" : ""}>
        {this.$slots.default}
      </div>
    );
  }
})
